package com.sds.service.impl;

import com.sds.service.OrderlinessService;
import org.springframework.stereotype.Service;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class OrderlinessServiceImpl implements OrderlinessService {

    private volatile boolean volatileFlag = false;
    private final Object syncLock = new Object();

    /**
     * 1、as-if-serial语义
     * i++ 和 j = j * 100; j = j + 100;。这两个操作都会按照它们在代码中的顺序执行，这就是 as-if-serial 语义，
     * 即使在实际的执行过程中，CPU 可能会对这些指令进行重排序，但是它必须保证最终的结果与按照程序顺序执行的结果一致
     */
    @Override
    public void asIfSerialMethod() {
        int i = 0;
        i++; // 这个操作将总是发生在i的初始化之后

        int j = 200;
        j = j * 100;
        j = j + 100; // 这个操作将总是发生在j的初始化之后
    }

    /**
     * 2、happens-before
     * 使用了 synchronized 关键字，这就保证了 happens-before 原则，
     * 即在同一个锁的 unlock 操作 happens-before 此锁的 lock 操作
     */
    @Override
    public void happensBeforeMethod() {
        Thread t1 = new Thread(() -> {
            synchronized (syncLock) {
                volatileFlag = true;
            }
        });
        t1.start();

        synchronized (syncLock) {
            if (volatileFlag) {
                System.out.println("The flag is true");
            }
        }
    }

    /**
     * 3、volatile关键字
     * 由于 volatileFlag 是一个 volatile 变量，这就保证了 volatile 的内存语义，
     * 即对一个 volatile 变量的写操作 happens-before 对此变量的任意读操作
     */
    @Override
    public void volatileMethod() {
        Thread t1 = new Thread(() -> {
            while (volatileFlag) {
                // ....
            }
            System.out.println("t1 thread ends");
        });
        t1.start();
        volatileFlag = false;
    }
}